package com.hzz.framework.web.controller;


import com.github.pagehelper.PageInfo;
import com.hzz.framework.ObjectCopy;
import com.hzz.framework.PageUtil;
import com.hzz.framework.dto.PageDto;
import com.hzz.framework.util.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import org.springframework.validation.BindingResult;
import org.springframework.validation.ObjectError;
import org.springframework.web.bind.WebDataBinder;
import org.springframework.web.bind.annotation.InitBinder;
import org.springframework.web.bind.annotation.ModelAttribute;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException;
import java.io.PrintWriter;
import java.math.BigDecimal;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.util.*;

public class BaseController {
    /**
     * 线程池
     */
    @Autowired
    protected ThreadPoolTaskExecutor taskExecutor;

    protected HttpServletRequest request;
    protected HttpServletResponse response;
    protected HttpSession session;

    @ModelAttribute
    public void setReqAndRes(HttpServletRequest request, HttpServletResponse response, HttpSession session) {
        this.request = request;
        this.response = response;
        this.session = session;
        this.request.setAttribute("basePath", getBasePath());
        this.request.setAttribute("ctxPath", request.getContextPath());
    }

    /***
     * 返回上次访问链接
     *
     * @return
     */
    public String getBackPath() {
        return request.getHeader("referer");
    }

    /***
     * 输出
     *
     * @return
     * @throws IOException
     */
    public PrintWriter getWriter() throws IOException {
        response.setCharacterEncoding("utf-8");
        response.setContentType("text/html;charset=utf-8");

        return response.getWriter();
    }

    /**
     * 获取用户IP
     */
    public String getIpAddr() {
        return IpUtil.getIpAddr(request);
    }

    public String getBasePath() {
        String path = request.getContextPath();
        String basePath = null;
        // log.info("访问端口号："+ request.getServerPort());
        if (request.getServerPort() != 80) {
            basePath = request.getScheme() + "://" + request.getServerName() + ":" + request.getServerPort() + path;
        } else {
            basePath = request.getScheme() + "://" + request.getServerName() + path;
        }
        return basePath + "/";
    }

    /**
     * 获取参数绑定错误消息
     *
     * @param bindingResult
     * @return
     */
    public String getBindErrorMsg(BindingResult bindingResult) {
        StringBuilder errorMsg = new StringBuilder();
        List<ObjectError> errorList = bindingResult.getAllErrors();
        for (ObjectError error : errorList) {
            errorMsg.append(error.getDefaultMessage()).append(";");
        }
        return errorMsg.toString();
    }

    public Integer getPageNum(Object obj) {
        Object pageNum = ReflectUtil.getValueByFieldName(obj, "pageNum");
        return ValidatorUtil.notEmpty("" + pageNum) ? Integer.parseInt("" + pageNum) : 1;
    }

    public PageDto getPageDto(PageInfo pageInfo) {
        return PageUtil.copy(pageInfo);
    }

    public <T> T copyTo(Object obj, Class<T> toObj) throws Exception {
        if (obj == null) {
            return null;
        }
        return ObjectCopy.copyTo(obj, toObj);
    }

    public <T> List<T> copyTo(List from, Class<T> to) {
        if (from == null) {
            return null;
        }
        return ObjectCopy.copyTo(from, to);
    }

    @InitBinder
    public void initBinder(WebDataBinder binder) {
        // SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd
        // HH:mm:ss");
        // dateFormat.setLenient(false);
        // binder.registerCustomEditor(Date.class, new
        // CustomDateEditor(dateFormat, true));
        // 处理BigDecimal的自动装载问题
        binder.registerCustomEditor(BigDecimal.class, new CustomBigDecimalEditor());
        // 处理10位日期格式的自动装载问题
        binder.registerCustomEditor(Date.class, new CustomDateEditor());
    }


    /**
     * 获取客户端浏览器类型、编码下载文件名
     *
     * @param request
     * @param fileName
     * @return String
     */
    public void setResponseHeader(HttpServletRequest request, HttpServletResponse response, String fileName) {
        try {
            String userAgent = request.getHeader("User-Agent");
            String rtn = "";
            String new_filename = URLEncoder.encode(fileName, "UTF8");
            // 如果没有UA，则默认使用IE的方式进行编码，因为毕竟IE还是占多数的
            rtn = "filename=\"" + new_filename + "\"";
            if (userAgent != null) {
                userAgent = userAgent.toLowerCase();
                // Opera浏览器只能采用filename*
                if (userAgent.indexOf("msie") != -1 || userAgent.indexOf("edge") != -1) {
                    rtn = "filename=\"" + new_filename + "\"";
                } else if (userAgent.indexOf("opera") != -1) {
                    rtn = "filename*=UTF-8''" + new_filename;
                }
                // Safari浏览器，只能采用ISO编码的中文输出
                else if (userAgent.indexOf("safari") != -1) {
                    rtn = "filename=\"" + new String(fileName.getBytes(StandardCharsets.UTF_8), "ISO8859-1") + "\"";
                }
                // FireFox浏览器，可以使用MimeUtility或filename*或ISO编码的中文输出
                else if (userAgent.indexOf("mozilla") != -1) {
                    rtn = "filename*=UTF-8''" + new_filename;
                } else {
                    rtn = "filename=\"" + new_filename + "\"";
                }
            }
            response.reset(); // 清空输出流
            response.setContentType("application/octet-stream");
            // 设置响应正文的MIME类型
            response.setContentType("Content-Disposition;charset=UTF8");
            response.setHeader("Content-Disposition", "attachment;" + rtn);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    protected static Map<String, Set<String>> currAreaMap = new HashMap();
    protected static Map<String, Set<String>> childAreaMap = new HashMap();

    static {
        Set<String> childArea1 = new HashSet();
        childArea1.add("市级");
        childArea1.add("县级");
        childArea1.add("乡镇级");
        childArea1.add("村级");

        Set<String> childArea2 = new HashSet();
        childArea2.add("县级");
        childArea2.add("乡镇级");
        childArea2.add("村级");

        Set<String> childArea3 = new HashSet();
        childArea3.add("乡镇级");
        childArea3.add("村级");

        Set<String> childArea4 = new HashSet();
        childArea4.add("村级");

        childAreaMap.put("省级", childArea1);
        childAreaMap.put("市级", childArea2);
        childAreaMap.put("县级", childArea3);
        childAreaMap.put("乡镇级", childArea4);


        Set<String> currArea1 = new HashSet();
        currArea1.add("省级");
        currArea1.add("市级");
        currArea1.add("县级");
        currArea1.add("乡镇级");
        currArea1.add("村级");

        Set<String> currArea2 = new HashSet();
        currArea2.add("市级");
        currArea2.add("县级");
        currArea2.add("乡镇级");
        currArea2.add("村级");

        Set<String> currArea3 = new HashSet();
        currArea3.add("县级");
        currArea3.add("乡镇级");
        currArea3.add("村级");

        Set<String> currArea4 = new HashSet();
        currArea4.add("乡镇级");
        currArea4.add("村级");

        Set<String> currArea5 = new HashSet();
        currArea5.add("村级");

        currAreaMap.put("省级", currArea1);
        currAreaMap.put("市级", currArea2);
        currAreaMap.put("县级", currArea3);
        currAreaMap.put("乡镇级", currArea4);
        currAreaMap.put("村级", currArea5);
    }
}